package com.goldze.mvvmhabit.widght.expandswipe;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ObservableList;
import androidx.databinding.OnRebindCallback;
import androidx.databinding.ViewDataBinding;
import androidx.recyclerview.widget.RecyclerView;

import com.goldze.mvvmhabit.R;
import com.goldze.mvvmhabit.utils.Utils;
import com.goldze.mvvmhabit.widght.ExpandableItemIndicator;
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange;
import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableDraggableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableItemState;
import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableItemViewHolder;
import com.h6ah4i.android.widget.advrecyclerview.expandable.ExpandableSwipeableItemAdapter;
import com.h6ah4i.android.widget.advrecyclerview.expandable.RecyclerViewExpandableItemManager;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstants;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemState;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionMoveToSwipedDirection;
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractDraggableSwipeableItemViewHolder;
import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractExpandableItemAdapter;

import java.lang.ref.WeakReference;
import java.util.List;

import me.goldze.mvvmhabit.utils.KLog;

public class ExpandSwipeRvAdapter<T extends ExpandSwipeViewModel> extends AbstractExpandableItemAdapter<ExpandSwipeRvAdapter.ParentViewHolder, ExpandSwipeRvAdapter.ChildViewHolder>
        implements ExpandableDraggableItemAdapter<ExpandSwipeRvAdapter.ParentViewHolder, ExpandSwipeRvAdapter.ChildViewHolder>,
         BindingExpandSwipeAdapter<T> , ExpandableSwipeableItemAdapter<ExpandSwipeRvAdapter.ParentViewHolder, ExpandSwipeRvAdapter.ChildViewHolder> {

    private RecyclerViewExpandableItemManager mExpandableItemManager;
    private ExpandSwipeItemBinding<T> parentBinding;
    private ExpandSwipeItemBinding<T> childBinding;
    private List<T> items;
    private LayoutInflater inflater;
    private WeakRefrenceParentListChangeCallBack<T> callBack = new WeakRefrenceParentListChangeCallBack<T>(this);
    private RecyclerView recyclerView;

    public ExpandSwipeRvAdapter(RecyclerViewExpandableItemManager mExpandableItemManager) {
        this.mExpandableItemManager = mExpandableItemManager;
        setHasStableIds(true);
    }

    @Override
    public int getGroupCount() {
        return items==null?0: items.size();
    }

    @Override
    public int getChildCount(int groupPosition) {
        if(items==null){
            return 0;
        }
        return items.get(groupPosition).getChildCount();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return items.get(groupPosition).getId();
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return items.get(groupPosition).getChild(childPosition).getId();
    }

    @NonNull
    @Override
    public ParentViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
        if(inflater==null){
            inflater = LayoutInflater.from(parent.getContext());
        }
        ViewDataBinding dataBinding = oncreateBinding(inflater,viewType,parent);
        final ParentViewHolder holder = new ParentViewHolder(dataBinding.getRoot());
        dataBinding.addOnRebindCallback(new OnRebindCallback() {
            @Override
            public boolean onPreBind(ViewDataBinding binding) {
                return recyclerView!=null && recyclerView.isComputingLayout();
            }

            @Override
            public void onCanceled(ViewDataBinding binding) {
              if(recyclerView==null ||  recyclerView.isComputingLayout()){
                  return;
              }
              int adapterPosition = holder.getAdapterPosition();
              if(adapterPosition!=RecyclerView.NO_POSITION){
                  notifyItemChanged(adapterPosition);
              }
            }
        });
        return holder;
    }

    @NonNull
    @Override
    public ChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
        if(inflater==null){
            inflater = LayoutInflater.from(parent.getContext());
        }
        ViewDataBinding dataBinding = oncreateBinding(inflater,viewType,parent);
        final ChildViewHolder holder = new ChildViewHolder(dataBinding.getRoot());
        dataBinding.addOnRebindCallback(new OnRebindCallback() {
            @Override
            public boolean onPreBind(ViewDataBinding binding) {
                return recyclerView!=null && recyclerView.isComputingLayout();
            }

            @Override
            public void onCanceled(ViewDataBinding binding) {
                if(recyclerView==null ||  recyclerView.isComputingLayout()){
                    return;
                }
                int adapterPosition = holder.getAdapterPosition();
                if(adapterPosition!=RecyclerView.NO_POSITION){
                    notifyItemChanged(adapterPosition);
                }
            }
        });
        return holder;
    }

    @Override
    public int getGroupItemViewType(int groupPosition) {
        parentBinding.onItemBind(groupPosition,items.get(groupPosition));
        return parentBinding.getLayoutRes();
    }

    @Override
    public int getChildItemViewType(int groupPosition, int childPosition) {
        childBinding.onItemBind(groupPosition,childPosition, (T) items.get(groupPosition).getChild(childPosition));
        return childBinding.getLayoutRes();
    }

    @Override
    public void onBindGroupViewHolder(@NonNull ParentViewHolder holder, int groupPosition, int viewType) {
        T item = items.get(groupPosition);
        ViewDataBinding binding = DataBindingUtil.getBinding(holder.itemView);
        onBindParentBinding(binding,parentBinding.getVaribleId(),parentBinding.getLayoutRes(),groupPosition,item);
    }

    @Override
    public void onBindChildViewHolder(@NonNull ChildViewHolder holder, int groupPosition, int childPosition, int viewType) {
        T item = (T) items.get(groupPosition).getChild(childPosition);
        ViewDataBinding binding = DataBindingUtil.getBinding(holder.itemView);
        onBindChildBinding(binding,childBinding.getVaribleId(),childBinding.getLayoutRes(),groupPosition,childPosition,item);
    }

    @Override
    public boolean onCheckCanExpandOrCollapseGroup(@NonNull ParentViewHolder holder, int groupPosition, int x, int y, boolean expand) {
        return true;
    }

    @Override
    public void setTtemBinding(ExpandSwipeItemBinding parentBinding, ExpandSwipeItemBinding childBinding) {
        this.parentBinding  =  parentBinding;
        this.childBinding = childBinding;
    }

    @Override
    public ExpandSwipeItemBinding getParentBinding() {
        return parentBinding;
    }

    @Override
    public ExpandSwipeItemBinding getChildBinding() {
        return childBinding;
    }

    @Override
    public void setItems(@Nullable List items) {
        if(this.items == items){
            return;
        }
        if(recyclerView!=null){

            if(this.items instanceof ObservableList){
                ((ObservableList<T>) this.items).removeOnListChangedCallback(callBack);
            }
            if(items instanceof ObservableList){
                ((ObservableList<T>) items).addOnListChangedCallback(callBack);
            }
            for (int i = 0; i < this.items.size(); i++) {
                ExpandSwipeViewModel t =this. items.get(i);
                final    WeakReferenceChildListChangeCallBack<T> childListChangeCallBack = new WeakReferenceChildListChangeCallBack<T>(this,i);
                if(t.getItems() instanceof ObservableList){
                    ((ObservableList<T>)t.getItems()).removeOnListChangedCallback(childListChangeCallBack);
                }
                if(t.getItems() instanceof ObservableList){
                    ((ObservableList<T>)t.getItems()).addOnListChangedCallback(childListChangeCallBack);
                }
            }
        }
        this.items = items;
    }
    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        if (this.recyclerView == null && items != null && items instanceof ObservableList) {
            ((ObservableList<T>) items).addOnListChangedCallback(callBack);

            for (int i = 0; i < this.items.size(); i++) {
                ExpandSwipeViewModel item = this.items.get(i);
                final WeakReferenceChildListChangeCallBack<T> childCallback = new WeakReferenceChildListChangeCallBack<>(this, i);

                if (item.getItems() instanceof ObservableList) {
                    ((ObservableList<T>) item.getItems()).addOnListChangedCallback(childCallback);
                }
            }
        }
        this.recyclerView = recyclerView;
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        if (this.recyclerView != null && items != null && items instanceof ObservableList) {
            ((ObservableList<T>) items).removeOnListChangedCallback(callBack);

            for (int i = 0; i < this.items.size(); i++) {
                ExpandSwipeViewModel item = this.items.get(i);
                final WeakReferenceChildListChangeCallBack<T> childCallback = new WeakReferenceChildListChangeCallBack<>(this, i);

                if (item.getItems() instanceof ObservableList) {
                    ((ObservableList<T>) item.getItems()).removeOnListChangedCallback(childCallback);
                }
            }
        }
        this.recyclerView = null;
    }
    @Override
    public T getAdapterItem(int position) {
        return items.get(position);
    }

    @Override
    public ViewDataBinding oncreateBinding(LayoutInflater inflater, int layoutRes, ViewGroup viewGroup) {
        return DataBindingUtil.inflate(inflater,layoutRes,viewGroup,false);
    }

    @Override
    public void onBindParentBinding(ViewDataBinding dataBinding, int varibleId, int layoutRes, int parentPosition, T item) {
        if(parentBinding.Bind(dataBinding,item)){
            dataBinding.executePendingBindings();
        }
    }

    @Override
    public void onBindChildBinding(ViewDataBinding viewDataBinding, int varibleId, int layoutRes, int parentPosition, int childPosition, T item) {
        if(childBinding.Bind(viewDataBinding,item)){
            viewDataBinding.executePendingBindings();
        }
    }

    @Override
    public boolean onCheckGroupCanStartDrag(@NonNull ParentViewHolder holder, int groupPosition, int x, int y) {
        // x, y --- relative from the itemView's top-left
        final View containerView = holder.mContainer;
        final View dragHandleView = holder.mDragHandle;

        final int offsetX = containerView.getLeft() + (int) (containerView.getTranslationX() + 0.5f);
        final int offsetY = containerView.getTop() + (int) (containerView.getTranslationY() + 0.5f);

        return Utils.hitTest(dragHandleView, x - offsetX, y - offsetY);
    }

    @Override
    public boolean onCheckChildCanStartDrag(@NonNull ChildViewHolder holder, int groupPosition, int childPosition, int x, int y) {
        // x, y --- relative from the itemView's top-left
        final View containerView = holder.mContainer;
        final View dragHandleView = holder.mDragHandle;

        final int offsetX = containerView.getLeft() + (int) (containerView.getTranslationX() + 0.5f);
        final int offsetY = containerView.getTop() + (int) (containerView.getTranslationY() + 0.5f);

        return Utils.hitTest(dragHandleView, x - offsetX, y - offsetY);
    }

    @Override
    public ItemDraggableRange onGetGroupItemDraggableRange(@NonNull ParentViewHolder holder, int groupPosition) {
        return null;
    }

    @Override
    public ItemDraggableRange onGetChildItemDraggableRange(@NonNull ChildViewHolder holder, int groupPosition, int childPosition) {
        return null;
    }

    @Override
    public void onMoveGroupItem(int fromGroupPosition, int toGroupPosition) {

    }

    @Override
    public void onMoveChildItem(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition) {

    }

    @Override
    public boolean onCheckGroupCanDrop(int draggingGroupPosition, int dropGroupPosition) {
        return false;
    }

    @Override
    public boolean onCheckChildCanDrop(int draggingGroupPosition, int draggingChildPosition, int dropGroupPosition, int dropChildPosition) {
        return false;
    }

    @Override
    public void onGroupDragStarted(int groupPosition) {
        notifyDataSetChanged();
    }

    @Override
    public void onChildDragStarted(int groupPosition, int childPosition) {
        notifyDataSetChanged();
    }

    @Override
    public void onGroupDragFinished(int fromGroupPosition, int toGroupPosition, boolean result) {
        notifyDataSetChanged();
    }

    @Override
    public void onChildDragFinished(int fromGroupPosition, int fromChildPosition, int toGroupPosition, int toChildPosition, boolean result) {
        notifyDataSetChanged();
    }

    private class Swipeable implements SwipeableItemConstants {

    }
    @Override
    public SwipeResultAction onSwipeGroupItem(@NonNull ParentViewHolder holder, int groupPosition, int result) {
        switch (result) {
            // swipe right
            case Swipeable.RESULT_SWIPED_RIGHT:
                if (items.get(groupPosition).isPinned()) {
                    // pinned --- back to default position
                    return new GroupUnpinResultAction(this, groupPosition);
                } else {
                    // not pinned --- remove
                    return new GroupSwipeRightResultAction(this, groupPosition);
                }
                // swipe left -- pin
            case Swipeable.RESULT_SWIPED_LEFT:
                return new GroupSwipeLeftResultAction(this, groupPosition);
            // other --- do nothing
            case Swipeable.RESULT_CANCELED:
            default:
                if (groupPosition != RecyclerView.NO_POSITION) {
                    return new GroupUnpinResultAction(this, groupPosition);
                } else {
                    return null;
                }
        }
    }

    @Override
    public SwipeResultAction onSwipeChildItem(@NonNull ChildViewHolder holder, int groupPosition, int childPosition, int result) {
        switch (result) {
            // swipe right
            case Swipeable.RESULT_SWIPED_RIGHT:
                if (items.get(groupPosition).getChild(childPosition).isPinned()) {
                    // pinned --- back to default position
                    return new ChildUnpinResultAction(this, groupPosition, childPosition);
                } else {
                    // not pinned --- remove
                    return new ChildSwipeRightResultAction(this, groupPosition, childPosition);
                }
                // swipe left -- pin
            case Swipeable.RESULT_SWIPED_LEFT:
                return new ChildSwipeLeftResultAction(this, groupPosition, childPosition);
            // other --- do nothing
            case Swipeable.RESULT_CANCELED:
            default:
                if (groupPosition != RecyclerView.NO_POSITION) {
                    return new ChildUnpinResultAction(this, groupPosition, childPosition);
                } else {
                    return null;
                }
        }
    }

    @Override
    public int onGetGroupItemSwipeReactionType(@NonNull ParentViewHolder holder, int groupPosition, int x, int y) {
        if (onCheckGroupCanStartDrag(holder, groupPosition, x, y)) {
            return Swipeable.REACTION_CAN_NOT_SWIPE_BOTH_H;
        }

        return Swipeable.REACTION_CAN_SWIPE_BOTH_H;
    }

    @Override
    public int onGetChildItemSwipeReactionType(@NonNull ChildViewHolder holder, int groupPosition, int childPosition, int x, int y) {
        if (onCheckChildCanStartDrag(holder, groupPosition, childPosition, x, y)) {
            return Swipeable.REACTION_CAN_NOT_SWIPE_BOTH_H;
        }

        return Swipeable.REACTION_CAN_SWIPE_BOTH_H;
    }

    @Override
    public void onSwipeGroupItemStarted(@NonNull ParentViewHolder holder, int groupPosition) {
        notifyDataSetChanged();
    }

    @Override
    public void onSwipeChildItemStarted(@NonNull ChildViewHolder holder, int groupPosition, int childPosition) {
        notifyDataSetChanged();
    }

    @Override
    public void onSetGroupItemSwipeBackground(@NonNull ParentViewHolder holder, int groupPosition, int type) {
        KLog.e("sss   "+type);
        int bgResId = 0;
        switch (type) {
            case Swipeable.DRAWABLE_SWIPE_NEUTRAL_BACKGROUND:
                bgResId = R.drawable.bg_swipe_item_neutral;
                break;
            case Swipeable.DRAWABLE_SWIPE_LEFT_BACKGROUND:
                bgResId = R.drawable.bg_swipe_group_item_left;
                break;
            case Swipeable.DRAWABLE_SWIPE_RIGHT_BACKGROUND:
                bgResId = R.drawable.bg_swipe_group_item_right;
                break;
        }

        holder.itemView.setBackgroundResource(bgResId);
    }

    @Override
    public void onSetChildItemSwipeBackground(@NonNull ChildViewHolder holder, int groupPosition, int childPosition, int type) {
        int bgResId = 0;
        switch (type) {
            case Swipeable.DRAWABLE_SWIPE_NEUTRAL_BACKGROUND:
                bgResId = R.drawable.bg_swipe_item_neutral;
                break;
            case Swipeable.DRAWABLE_SWIPE_LEFT_BACKGROUND:
                bgResId = R.drawable.bg_swipe_item_left;
                break;
            case Swipeable.DRAWABLE_SWIPE_RIGHT_BACKGROUND:
                bgResId = R.drawable.bg_swipe_item_right;
                break;
        }

        holder.itemView.setBackgroundResource(bgResId);
    }


    private static class GroupSwipeLeftResultAction extends SwipeResultActionMoveToSwipedDirection {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;
        private boolean mSetPinned;

        GroupSwipeLeftResultAction(ExpandSwipeRvAdapter adapter, int groupPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();



            ExpandSwipeViewModel item = mAdapter.getAdapterItem(mGroupPosition);

            if (!item.isPinned()) {
                item.setPinned(true);
                mAdapter.mExpandableItemManager.notifyGroupItemChanged(mGroupPosition);
                mSetPinned = true;
            }
        }

        @Override
        protected void onSlideAnimationEnd() {
            super.onSlideAnimationEnd();

//            if (mSetPinned && mAdapter.mEventListener != null) {
//                mAdapter.mEventListener.onGroupItemPinned(mGroupPosition);
//            }
        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }

    private static class GroupSwipeRightResultAction extends SwipeResultActionRemoveItem {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;

        GroupSwipeRightResultAction(ExpandSwipeRvAdapter adapter, int groupPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();

            mAdapter.items.remove(mGroupPosition);
            mAdapter.mExpandableItemManager.notifyGroupItemRemoved(mGroupPosition);
        }

        @Override
        protected void onSlideAnimationEnd() {
            super.onSlideAnimationEnd();


        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }

    private static class GroupUnpinResultAction extends SwipeResultActionDefault {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;

        GroupUnpinResultAction(ExpandSwipeRvAdapter adapter, int groupPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();

            ExpandSwipeViewModel item = (ExpandSwipeViewModel) mAdapter.items.get(mGroupPosition);
            if (item.isPinned()) {
                item.setPinned(false);
                mAdapter.mExpandableItemManager.notifyGroupItemChanged(mGroupPosition);
            }
        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }






    private static class ChildSwipeLeftResultAction extends SwipeResultActionMoveToSwipedDirection {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;
        private final int mChildPosition;
        private boolean mSetPinned;

        ChildSwipeLeftResultAction(ExpandSwipeRvAdapter adapter, int groupPosition, int childPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
            mChildPosition = childPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();
            ExpandSwipeViewModel item = mAdapter.getAdapterItem(mGroupPosition).getChild(mChildPosition);

            if (!item.isPinned()) {
                item.setPinned(true);
                mAdapter.mExpandableItemManager.notifyChildItemChanged(mGroupPosition, mChildPosition);
                mSetPinned = true;
            }
        }

        @Override
        protected void onSlideAnimationEnd() {
            super.onSlideAnimationEnd();

//            if (mSetPinned && mAdapter.mEventListener != null) {
//                mAdapter.mEventListener.onChildItemPinned(mGroupPosition, mChildPosition);
//            }
        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }

    private static class ChildSwipeRightResultAction extends SwipeResultActionRemoveItem {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;
        private final int mChildPosition;

        ChildSwipeRightResultAction(ExpandSwipeRvAdapter adapter, int groupPosition, int childPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
            mChildPosition = childPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();

            mAdapter.getAdapterItem(mGroupPosition).getItems().remove(mChildPosition);
            mAdapter.mExpandableItemManager.notifyChildItemRemoved(mGroupPosition, mChildPosition);
        }

        @Override
        protected void onSlideAnimationEnd() {
            super.onSlideAnimationEnd();

//            if (mAdapter.mEventListener != null) {
//                mAdapter.mEventListener.onChildItemRemoved(mGroupPosition, mChildPosition);
//            }
        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }

    private static class ChildUnpinResultAction extends SwipeResultActionDefault {
        private ExpandSwipeRvAdapter mAdapter;
        private final int mGroupPosition;
        private final int mChildPosition;

        ChildUnpinResultAction(ExpandSwipeRvAdapter adapter, int groupPosition, int childPosition) {
            mAdapter = adapter;
            mGroupPosition = groupPosition;
            mChildPosition = childPosition;
        }

        @Override
        protected void onPerformAction() {
            super.onPerformAction();
            ExpandSwipeViewModel item = mAdapter.getAdapterItem(mGroupPosition).getChild(mChildPosition);
            if (item.isPinned()) {
                item.setPinned(false);
                mAdapter.mExpandableItemManager.notifyChildItemChanged(mGroupPosition, mChildPosition);
            }
        }

        @Override
        protected void onCleanUp() {
            super.onCleanUp();
            // clear the references
            mAdapter = null;
        }
    }

    public static class ChildViewHolder extends BaseViewHolder{

        public ChildViewHolder(@NonNull View v) {
            super(v);
        }
    }

    public static class ParentViewHolder extends BaseViewHolder{
        public ExpandableItemIndicator mIndicator;
        public ParentViewHolder(@NonNull View v) {
            super(v);
            mIndicator = v.findViewById(R.id.indicator);

        }
    }

    public static class BaseViewHolder extends AbstractDraggableSwipeableItemViewHolder implements ExpandableItemViewHolder {
        private final ExpandableItemState mExpandState = new ExpandableItemState();
        public FrameLayout mContainer;
        public View mDragHandle;
        public TextView mTextView;
        public BaseViewHolder(@NonNull View v) {
            super(v);
            mContainer = v.findViewById(R.id.container);
            mDragHandle = v.findViewById(R.id.drag_handle);
            mTextView = v.findViewById(android.R.id.text1);
        }

        @NonNull
        @Override
        public View getSwipeableContainerView() {
            return mContainer;
        }

        @Override
        public void setExpandStateFlags(int flags) {
            mExpandState.setFlags(flags);
        }

        @Override
        public int getExpandStateFlags() {
            return mExpandState.getFlags();
        }

        @NonNull
        @Override
        public ExpandableItemState getExpandState() {
            return mExpandState;
        }
    }

    public static class WeakRefrenceParentListChangeCallBack<T extends  ExpandSwipeViewModel> extends ObservableList.OnListChangedCallback<ObservableList<T>>{
        private WeakReference<ExpandSwipeRvAdapter<T>> adapterRef;

        public WeakRefrenceParentListChangeCallBack(ExpandSwipeRvAdapter<T> adapterRef) {
            this.adapterRef = new WeakReference<>(adapterRef);
        }

        @Override
        public void onChanged(ObservableList sender) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }

        }

        @Override
        public void onItemRangeChanged(ObservableList sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyGroupAndChildrenItemsChanged(positionStart);
        }

        @Override
        public void onItemRangeInserted(ObservableList sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyGroupItemRangeInserted(positionStart,itemCount);
        }

        @Override
        public void onItemRangeMoved(ObservableList sender, int fromPosition, int toPosition, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            for (int i = 0; i < itemCount; i++) {
                adapter.mExpandableItemManager.notifyGroupItemRemoved(fromPosition);
            }

        }

        @Override
        public void onItemRangeRemoved(ObservableList sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyGroupItemRangeRemoved(positionStart,itemCount);
        }
    }

    public static class WeakReferenceChildListChangeCallBack<T extends ExpandSwipeViewModel> extends ObservableList.OnListChangedCallback<ObservableList<T>>{
        private WeakReference<ExpandSwipeRvAdapter<T>> adapterRef;
        private int parandPosition;
        public WeakReferenceChildListChangeCallBack(ExpandSwipeRvAdapter<T> adapterRef,int parandPosition) {
            this.adapterRef = new WeakReference<>(adapterRef);
            this.parandPosition = parandPosition;
        }

        @Override
        public void onChanged(ObservableList<T> sender) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
        }

        @Override
        public void onItemRangeChanged(ObservableList<T> sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyChildItemRangeChanged(parandPosition,positionStart,itemCount);
        }

        @Override
        public void onItemRangeInserted(ObservableList<T> sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyChildItemRangeInserted(parandPosition,positionStart,itemCount);
        }

        @Override
        public void onItemRangeMoved(ObservableList<T> sender, int fromPosition, int toPosition, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            for (int i = 0; i < itemCount; i++) {
                adapter.mExpandableItemManager.notifyChildItemMoved(parandPosition,fromPosition,toPosition);
            }

        }

        @Override
        public void onItemRangeRemoved(ObservableList<T> sender, int positionStart, int itemCount) {
            ExpandSwipeRvAdapter<T> adapter = adapterRef.get();
            if(adapter==null){
                return;
            }
            Utils.ensureChangeOnMainThread();
            adapter.mExpandableItemManager.notifyChildItemRangeRemoved(parandPosition,positionStart,itemCount);
        }
    }
}
